【アップデート】Pythonと.NETでもSnapStartが利用可能になりました!!
リテールアプリ共創部@大阪の岩田です。
re:Invent 2022で発表されたSnapStartは設定変更のみでLambdaのコールドスタートを改善できる非常に魅力的な機能でした。しかしながら、サポートされるランタイムはJava11以上のみという状況が長らく続いており、他のランタイムを利用するユーザーは自身が利用するランタイムでもSnapStartが利用可能になるのを待ち望んでいたのではないでしょうか?
それがついに2024/11/18付けのアップデートでSnapStartがサポートするランタイムが増えました!!
従来のJavaに加えてPython3.12以上と.NET8以上(といっても.NETは8が最新ですが)のランタイムでSnapStartがサポートされています。
ちょっと設定を変更するだけでコールドスタートのレイテンシが改善されるので、LambdaのランタイムにPythonや.NETを利用されている方はぜひお試しください。
環境など
今回検証に利用したLambdaの設定は以下の通りです。
- ランタイム: Python3.12
- ランタイムバージョンARN:
arn:aws:lambda:us-east-1::runtime:7515e00d6763496e7a147ffa395ef5b0f0c1ffd6064130abb5ecde5a6d630e86
- パッケージサイズ
- コードサイズ: 1.5KB
- 紐づけたレイヤーのサイズ: 圧縮前で11M、圧縮後で2.8M
やってみる
さっそく自分が管理している適当なLambda FunctionでSnapStartを試してみます。
私はPython3.12のLambda × API Gatewayで構築したサンシャイン池崎BotというSlack Botを運用しているので、こちらのBotを使ってSnapStartの有効化を試してみます。
サンシャイン池崎BotはSAMでデプロイしているので、以下の通りSAMテンプレートにSnapStart関連の記述を追加しました。
...略
Resources:
SlackEvent:
Type: AWS::Serverless::Function
Properties:
# ↓追加
SnapStart:
ApplyOn: PublishedVersions
AutoPublishAlias: SnapStart
# ↑追加
変更箇所はたったこれだけです。
準備ができたらsam build
とsam deploy
でデプロイします。
デプロイが完了するとLambdaのSnapStartがPublishedVersions
となっていることが分かります。
適当にBotを起動させてX-Rayのトレース結果を見比べてみます。
SnapStart有効化前
まずSnapStartを有効化する前のトレース結果です。API GWからLambdaが起動されてから約250ms後にInit処理がスタートし、Init処理には1.01秒を要しています。
SnapStart有効化後
SnapStart有効化後はこちらです。
API GWからLambdaが起動されてから約120ms後にRestore処理がスタートし、Restore処理は559msで完了しています。
API GW → Lambdaという処理全体で見ると500ms程度高速化していることが分かります。
参考までに上記トレースに紐づくログです。
REPORT RequestId: 02fe2461-ddfa-4cc7-b513-f65adf73ae60 Duration: 16.29 ms Billed Duration: 64 ms Memory Size: 512 MB Max Memory Used: 83 MB Restore Duration: 558.86 ms Billed Restore Duration: 47 ms
XRAY TraceId: 1-673c237b-6507f76a25a2f9ba510f8f98 SegmentId: 6a5914043a0bd9ea Sampled: true
JavaのSnapStartと同様にRestore Duration
が出力されていることが分かります。
注意!!Java以外のランタイムでSnapStartを有効化すると追加料金が発生します
これまではSnapStartを有効化しても特に追加の料金は発生しなかったのですが、今回SnapStartがサポートされたPythonと.NETに関しては追加料金が発生するようです。
公式ドキュメントには以下のように記載されています
For Java managed runtimes, there's no additional cost for SnapStart. You're charged based on the number of requests for your functions, the time that it takes your code to run, and the memory configured for your function.
Javaだけが追加料金の対象外と記載されているので、今後他のランタイムでSnapStartがサポートされるようになった場合も恐らく追加料金が必要になりそうですね。
SnapStartの追加料金体系
SnapStartの追加料金は以下の2つの項目に対して発生します。いずれもLambdaのメモリ割当に比例して料金が変わります。
- キャッシュ
- SnapStartを有効化したLambdaのバージョン毎に課金が発生します。
- 最低3時間の課金が発生し、以後は1秒毎に課金されます。
- 東京リージョンの場合は
$0.0000015046 per GB-second
です。- メモリを1GB割り当てたLambdaのスナップショットを1秒維持するために $0.0000015046 の課金が発生します。
- 恐らくFirecrackerのスナップショットS3上に保存するためのストレージ料金などが必要という背景だろうと想像します。
- リストア
- スナップショットからLambda実行環境がリストアされるたびに課金が発生します。
- リストアの所要時間とは無関係でリストアが発生した回数とメモリ割り当てに依存して料金が変わります。
- 東京リージョンの場合は
$0.0001397998 for every GB restored
です。- メモリを1GB割り当てたLambdaのスナップショットを1回リストアするごとに $0.0001397998 の課金が発生します。
まとめ
簡単にではありますがSnapStartによってコールドスタートのレイテンシが改善されることを確認してみました。
今回は紹介していませんが、Pythonと.NETでもJavaと同様にhookポイントが提供されており、スナップショット取得の直前やリストア完了直後に任意の処理を差し込むことも可能です。このあたりの機能もうまく活用して処理を最適化していきたいですね。
他のランタイムもSnapStartに対応して全てのランタイムでSnapStartが利用可能になるのが待ち遠しいです!!
参考
- AWS Lambda now supports SnapStart for Python and .NET functions - AWS
- AWS Lambda SnapStart for Python and .NET functions is now generally available | AWS News Blog
- Improving startup performance with Lambda SnapStart - AWS Lambda
- [アップデート] JavaのLambda関数の実行を高速化するLambda SnapStartがリリースされました #reinvent | DevelopersIO